package tasks

import (
	"context"
	"encoding/json"
	"supershare/backend/models"
	"time"

	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
	"github.com/beego/beego/v2/task"
)

// InitOrderTasks 初始化订单相关的定时任务
func InitOrderTasks() {
	// 创建一个新的定时任务，每5分钟执行一次 CompleteOverdueOrders 函数
	orderTask := task.NewTask("completeOrderTask", "0 */5 * * * *", func(ctx context.Context) error {
		CompleteOverdueOrders()
		ConfirmPendingOrders()
		return nil
	})

	// 将任务添加到 Beego 的任务管理器中
	task.AddTask("completeOrderTask", orderTask)
}

// CompleteOverdueOrders 检查并完成超期的订单
// 该函数会查询所有状态为“已确认”且结束时间已过的订单，并将其状态更新为“已完成”。
// ConfirmPendingOrders 检查并确认待处理的订单
// 该函数会查询所有状态为“待确认”且开始时间已到的订单，并将其状态更新为“已确认”。
func ConfirmPendingOrders() {
	logs.Info("开始执行【确认待处理订单】定时任务")

	// 获取当前时间戳
	now := time.Now().Unix()

	// 查找需要更新的订单
	ordersToConfirm, err := models.FindPendingOrders(now)
	if err != nil {
		logs.Error("【确认待处理订单】任务执行失败: 查询订单时出错, %v", err)
		return
	}

	if len(ordersToConfirm) == 0 {
		logs.Info("【确认待处理订单】任务：没有需要处理的订单")
		return
	}

	// 提取订单ID和场地ID列表
	orderIDs := make([]int64, len(ordersToConfirm))
	venueIDs := make([]int64, len(ordersToConfirm))
	for i, order := range ordersToConfirm {
		orderIDs[i] = order.Id
		venueIDs[i] = order.VenueId
	}

	// 批量更新订单状态
	affected, err := models.BatchUpdateOrderStatus(orderIDs, models.OrderStatusProcessing)
	if err != nil {
		logs.Error("【确认待处理订单】任务执行失败: 批量更新订单状态时出错, %v", err)
		return
	}
	//批量更新场地状态为使用中
	logs.Info("【确认待处理订单】任务执行成功，共更新 %d 条订单状态为“已确认”", affected)

	// 批量更新场地状态为使用中
	affectedVenues, err := models.BatchUpdateVenueStatus(venueIDs, models.VenueStatusOccupied)
	if err != nil {
		logs.Error("【确认待处理订单】任务执行失败: 批量更新场地状态时出错, %v", err)
		return
	}
	logs.Info("【确认待处理订单】任务执行成功，共更新 %d 个场地状态为“使用中”", affectedVenues)
}

// CompleteOverdueOrders 检查并完成超期的订单
// 该函数会查询所有状态为“已确认”且结束时间已过的订单，并将其状态更新为“已完成”。
func CompleteOverdueOrders() {
	logs.Info("开始执行【完成超期订单】定时任务")

	// 获取当前时间戳
	now := time.Now().Unix()

	// 查找需要更新的订单
	ordersToComplete, err := models.FindOverdueConfirmedOrders(now)
	if err != nil {
		logs.Error("【完成超期订单】任务执行失败: 查询订单时出错, %v", err)
		return
	}

	if len(ordersToComplete) == 0 {
		logs.Info("【完成超期订单】任务：没有需要处理的订单")
		return
	}

	// 提取订单ID和场地ID列表
	orderIDs := make([]int64, len(ordersToComplete))
	venueIDs := make([]int64, len(ordersToComplete))
	for i, order := range ordersToComplete {
		orderIDs[i] = order.Id
		venueIDs[i] = order.VenueId
	}

	// 批量更新订单状态
	affected, err := models.BatchUpdateOrderStatus(orderIDs, models.OrderStatusCompleted)
	if err != nil {
		logs.Error("【完成超期订单】任务执行失败: 批量更新订单状态时出错, %v", err)
		return
	}
	logs.Info("【完成超期订单】任务执行成功，共更新 %d 条订单状态为“已完成”", affected)

	// 批量更新场地状态为待保洁
	affectedVenues, err := models.BatchUpdateVenueStatus(venueIDs, models.VenueStatusWaiting)
	if err != nil {
		logs.Error("【完成超期订单】任务执行失败: 批量更新场地状态时出错, %v", err)
		return
	}
	logs.Info("【完成超期订单】任务执行成功，共更新 %d 个场地状态为“待保洁”", affectedVenues)
	// 增加保洁记录
	createCleaningRecordsForOrder(orderIDs)
}

// createCleaningRecordsForOrder 为指定订单创建保洁记录
func createCleaningRecordsForOrder(orderIDs []int64) {
	o := orm.NewOrm()

	var cleaningRecords []models.CleaningRecord

	// 遍历所有订单ID
	for _, orderID := range orderIDs {
		// 获取订单信息
		var order models.Order
		err := o.QueryTable(new(models.Order)).Filter("id", orderID).One(&order)
		if err != nil {
			logs.Error("查询订单失败, orderID:", orderID, err)
			continue // 继续处理下一个订单
		}

		// 获取保洁设置
		var settings models.CleaningSetting
		err = o.QueryTable(new(models.CleaningSetting)).Filter("store_id", order.StoreId).One(&settings)
		if err != nil {
			logs.Error("查询保洁设置失败, storeID:", order.StoreId, err)
			continue // 继续处理下一个订单
		}

		// 解析保洁时段
		var timeSlots []map[string]string
		if err := json.Unmarshal([]byte(settings.CleaningTimeSlots), &timeSlots); err != nil {
			logs.Error("解析保洁时段失败, storeID:", order.StoreId, err)
			continue // 继续处理下一个订单
		}
		//获取门店保洁人员信息，并给保洁人员发送保洁任务提醒

		orderEndTime := time.Unix(order.EndTime, 0)
		orderEndHour := orderEndTime.Hour()
		// 获取该门店下的所有保洁人员
		var allCleaners []*models.Cleaner
		_, err = o.QueryTable(new(models.Cleaner)).Filter("franchise_id", settings.FranchiseId).All(&allCleaners)
		if err != nil {
			logs.Error("获取所有保洁人员失败, err:", err)
		}
		// 检查订单结束时间是否在任何一个保洁时段内
		for _, slot := range timeSlots {
			start, _ := time.Parse("15:04", slot["start"])
			end, _ := time.Parse("15:04", slot["end"])

			if orderEndHour >= start.Hour() && orderEndHour < end.Hour() {
				// 如果在时段内，则创建保洁记录
				cleaningStartTime := orderEndTime
				cleaningEndTime := cleaningStartTime.Add(time.Duration(settings.ReservedMinutes) * time.Minute)

				var cleanersForStore []models.Cleaner
				for _, cleaner := range allCleaners {
					var storeIDs []int64
					if err := json.Unmarshal([]byte(cleaner.StoreIDs), &storeIDs); err == nil {
						for _, sid := range storeIDs {
							if sid == order.StoreId {
								cleanersForStore = append(cleanersForStore, *cleaner)
								break
							}
						}
					}
				}

				cleaners := cleanersForStore
				var cleanerId int64
				if len(cleaners) > 0 {
					// 这里可以实现更复杂的分配逻辑，例如轮询、最少任务等
					// 目前简单选择第一个
					cleanerId = cleaners[0].Id
				}

				record := models.CleaningRecord{
					StoreId:   order.StoreId,
					VenueId:   order.VenueId,
					OrderId:   order.Id,
					Status:    0, // 待处理
					StartTime: cleaningStartTime,
					EndTime:   cleaningEndTime,
					CleanerId: cleanerId, // 分配保洁员
				}
				cleaningRecords = append(cleaningRecords, record)

				// 发送任务提醒 (此处为示例，需要实现具体的通知逻辑)
				if cleanerId != 0 {
					// sendCleaningTaskNotification(cleanerId, record)
					logs.Info("为保洁员 %d 创建了新的保洁任务, 记录ID: %d", cleanerId, record.Id)
				}

				break // 找到一个匹配的时段就足够了
			}
		}
	}

	// 批量插入保洁记录
	if len(cleaningRecords) > 0 {
		_, err := o.InsertMulti(len(cleaningRecords), cleaningRecords)
		if err != nil {
			logs.Error("批量创建保洁记录失败", err)
		}
	}
}
